/**
 *
 * 对 JNS 协议的封装，方便服务端使用。
 * @type {JNSProtocol}
 */

let Stick = require('./JNSProtocol');
const log4js = require("log4js");
const Log = log4js.getLogger("Frame");


class Frame {
    constructor(name, sock){
        this.name = name;
        this.out = sock;
        this.sock = sock;
        this.stick = new Stick();
        this.lastRecvTime = (new Date()).getTime();

        sock.on('data', (data) => {
            this.lastRecvTime = (new Date()).getTime();
            this.hook(data);
        });

        sock.on('close', (data) => {
            this.error("socketClose", this.name)
        });

        sock.on('error', (data) => {
            this.error("socketError", this.name)
        });

        this.stick.setErrorHandler(function (err) {
            this.error(err, this.name)
        })

        this.stick.setPingHandler( () => {
            this.out.write(this.stick.pongPack.data);
        })

        this.timer = setInterval( () =>{
            let now = (new Date()).getTime();
            if(  this.lastRecvTime + 60000 < now ){
                this.error("timeout", this.name)
            }

            if(  this.lastRecvTime + 15000 < now){
                Log.trace( this.name + " idle  " + (now - this.lastRecvTime))
                this.out.write(this.stick.pingPack.data);
            }

        }, 15000)
    }


    error(type, msg){
        this.errorHandler && this.errorHandler(type, msg);
        clearInterval(this.timer);
        this.sock.destroy();
    }

    hook(data) {
        this.lastRecvTime = (new Date()).getTime();
        Log.trace("收到原始数据", this.lastRecvTime)
        this.stick.hook(data);
    }

    onError(cb){
        this.errorHandler = cb;
    }

    onRequest(cb){
        this.stick.setRequestHandler( (id, data) =>{
            let msg = data.toString();
            msg = JSON.parse(msg);
            //Log.trace("onRequest", msg)
            cb(msg)
        })
    }


    onResponse(cb){
        this.stick.setResponseHandler( (id, data) => {
            let msg = data.toString();
            msg = JSON.parse(msg);
            //Log.trace("onResponse", msg)
            cb(msg)
        })
    }

    /**
     * 生成发送帧
     * @param out 输出源
     * @param data 数据 ： json 对象 。js 对象格式，json字符串格式，Buffer 格式
     */
     sendTo(out, data) {
        let pack = this.stick.pack(JSON.stringify(data), Stick.typeRes);
        out.write(pack.data);
        return pack.id;
    }

    send(data){
         return this.sendTo(this.out, data)
    }
}


module.exports = Frame;